Skip to content

mcp-server: return 200 for bare GET health probes#347

Merged
kvz merged 1 commit intomainfrom
mcp-health-probe
Mar 2, 2026
Merged

mcp-server: return 200 for bare GET health probes#347
kvz merged 1 commit intomainfrom
mcp-health-probe

Conversation

@kvz
Copy link
Copy Markdown
Member

@kvz kvz commented Mar 2, 2026

Summary

  • Directory crawlers like Glama probe MCP endpoints with a plain GET /mcp (no Accept: text/event-stream header)
  • The MCP SDK correctly rejects these with 406 "Not Acceptable", but crawlers interpret that as "server unhealthy"
  • For comparison, Stripe's mcp.stripe.com returns 401 on bare GET — crawlers read that as "alive but needs auth"
  • Our hosted endpoint at api2.transloadit.com/mcp currently shows as Unhealthy on Glama, blocking our PR on punkpeye/awesome-mcp-servers#1912 (80k stars)

Fix

Intercept bare GET requests (without Accept: text/event-stream) in http-request-handler.ts before they reach the SDK transport. Return a friendly JSON response:

{"name":"Transloadit MCP Server","status":"ok","docs":"https://transloadit.com/docs/sdks/mcp-server/"}

Real MCP clients always send Accept: text/event-stream (required by the Streamable HTTP spec), so they bypass this and reach the transport as before.

Test plan

  • New test: bare GET without SSE Accept → 200 with JSON status
  • New test: GET with SSE Accept → passes through to transport (not 200)
  • Existing tests pass (yarn check)

🤖 Generated with Claude Code

Directory crawlers like Glama probe MCP endpoints with a plain GET
(no Accept: text/event-stream header). The MCP SDK rejects these
with 406, but crawlers interpret that as "server unhealthy".

Intercept non-MCP GETs in the request handler and return a friendly
JSON status. Real MCP clients always send the SSE Accept header
and are unaffected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40ce162b44

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// a friendly JSON status so directory health-probes (Glama, uptime monitors)
// see a 200 instead of the SDK's opaque 406.
const accept = req.headers.accept ?? ''
if (req.method === 'GET' && !accept.includes('text/event-stream')) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize Accept header before SSE detection

HTTP media types are case-insensitive, so valid MCP clients can legally send mixed-case values like Accept: Text/Event-Stream. This check is case-sensitive, which means those requests are misclassified as health probes and get a 200 JSON status body instead of reaching transport.handleRequest, breaking the Streamable HTTP handshake for that client behavior. Converting the header to lowercase (or using media-type parsing) before matching would preserve compatibility.

Useful? React with 👍 / 👎.

@kvz kvz merged commit 5a07c08 into main Mar 2, 2026
10 checks passed
@kvz kvz deleted the mcp-health-probe branch March 2, 2026 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant